package org.dreamfly.netshop.security;

import java.util.HashSet;
import java.util.Set;

import org.dreamfly.netshop.dao.MemberDao;
import org.dreamfly.netshop.entity.TbMember;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;

/**
 * 实现SpringSecurity的UserDetailsService接口,实现获取用户Detail信息的回调函数.
 * 
 * @author calvin
 */
public class UserDetailServiceImpl implements UserDetailsService {
    @Autowired
    private MemberDao memberDao;

    /**
     * 获取用户Detail信息的回调函数.
     */
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {

        TbMember member = memberDao.loadByLoginName(userName);
        if (member == null)
            throw new UsernameNotFoundException("用户" + userName + " 不存在");

        GrantedAuthority[] grantedAuths = obtainGrantedAuthorities(member);

        // mini-web中无以下属性,暂时全部设为true.
        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

        org.springframework.security.userdetails.User userdetail = new org.springframework.security.userdetails.User(
                member.getName(), member.getPassword(), enabled, accountNonExpired, credentialsNonExpired,
                accountNonLocked, grantedAuths);

        return userdetail;
    }

    /**
     * 获得用户所有角色的权限.
     */
    private GrantedAuthority[] obtainGrantedAuthorities(User user) {
        Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();
        for (Role role : user.getRoles()) {
            for (Authority authority : role.getAuths()) {
                authSet.add(new GrantedAuthorityImpl(authority.getName()));
            }
        }
        return authSet.toArray(new GrantedAuthority[authSet.size()]);
    }
}
